## Reads in AOI position text files from Toii
## Will return tibble of columns sec, x, y, with rows for each timestamp/AOI position
get_xy_timestamp <- function(z){
x <- read_lines(z) %>%
  as_tibble() %>%
  rowid_to_column("ID")
# pull out timestamp rows
timestamps <- x %>%
  filter(str_detect(value, "timestamp")) %>%
  separate(value, into = c("throw","timestamp"), sep = " = ") %>%
  separate(timestamp, into = c("one","two","sec"), sep = ":") %>%
  select(sec) %>%
  mutate(sec = as.numeric(sec))
# Find AOI coordinate rows
xys <- x %>%
  mutate(find = str_detect(value, "X\tY"))
# first vertex (2 rows after each "XY" line)
xys_row <- which(xys$find) + 2
xy1 <- x %>%
  filter(ID %in% xys_row) %>%
  separate(value, into = c("x1","y1"), sep = "\t") %>%
  select(-ID)
# opposite vertex (2 more rows down)
xys_row <- xys_row + 2
xy2 <- x %>%
  filter(ID %in% xys_row) %>%
  separate(value, into = c("x2","y2"), sep = "\t") %>%
  select(-ID)
# Now get average XY position per timestamp
xys <- cbind(timestamps, xy1, xy2) %>%
  mutate_all(as.numeric) %>%
  rowwise() %>%
  mutate(x = mean(x1,x2),
         y = mean(y1, y2)) %>%
  select(sec, x, y)
}

Let’s give this a shot!!

Three Bears Forward

First let’s see who’s in our dataset. This is Test 1 - 3 Bears - Forward. We’re pulling cleaned-up names and assigned groups from our final dataset that we used in our AOI analysis. Then we are removing participants whose Three Bears Forward story wasn’t included in our AOI analysis due to <25% looking time or other reasons.

library(tidyverse)
library(openxlsx)
library(janitor)
# Get Three Bears data
data <- read.xlsx("Test1_Cindy_bears_FW_Examine for Spatial Referencing.xlsx") %>%
  clean_names() %>%
  rename(y = gaze_point_y_mc_spx,
         language = language_value,
         name = participant_name,
         group = group_value)
# Pull clean names and join to data (and add Laura2 for Laura (missing stories))
cleannames <- read_csv("partnames.csv") %>%
  distinct() %>%
  rename(name = participant) %>%
  filter(name != "Laura2")
data <- data %>% 
  left_join(cleannames, by = "name") %>%
  select(-name) %>%
  rename(name = new_participant) %>%
  filter(!is.na(name))
# Pull final group assignments and join to data
cleangroups <- read_csv("finaldataset.csv") %>%
  select(participant, maingroup) %>%
  rename(name = participant) %>%
  distinct()
data <- data %>% left_join(cleangroups, by = "name") %>%
  select(-group)
# Let's find out who was NOT included in Three Bears
excluded <- read_csv("finaldataset.csv") %>%
  select(participant, maingroup, story, direction, eye_exclude) %>%
  filter(story == "Goldilocks" & direction == "forward") %>%
  rename(name = participant) %>%
  select(name, eye_exclude)
data <- data %>% left_join(excluded, by = "name") %>%
  filter(!eye_exclude) %>%
  filter(!is.na(eye_exclude))
data %>% select(name, maingroup) %>% distinct()

Now let’s graph!!

Messy, I know, but already we can see some HearingNovice has big shifts downward. And some HearingLate too.

data %>%
  ggplot(aes(x = gaze_point_index, y = y, color = maingroup, group = name)) + geom_line() + 
  scale_y_reverse(limits = c(1200,0)) +
  theme_bw()

Group Averages

Next, let’s make group averages.

averaged_y <- data %>%
  group_by(maingroup, gaze_point_index) %>%
  summarise(y_mean = mean(y, na.rm = T),
            y_sd = sd(y, na.rm = T),
            y_count = n(),
            y_se = y_sd/sqrt(y_count))
averaged_y %>%
  ggplot() + 
  geom_line(aes(x = gaze_point_index, y = y_mean, color = maingroup)) +
  geom_ribbon(aes(x = gaze_point_index, 
                  ymin = y_mean-y_se, 
                  ymax = y_mean+y_se,
                  fill = maingroup), alpha = 0.5) +
  scale_y_reverse(limits = c(1200,0)) +
  theme_bw() +
  facet_wrap("maingroup")

averaged_y %>%
  ggplot() + 
  geom_line(aes(x = gaze_point_index, y = y_mean, color = maingroup)) +
  geom_ribbon(aes(x = gaze_point_index, 
                  ymin = y_mean-y_se, 
                  ymax = y_mean+y_se,
                  fill = maingroup), alpha = 0.5) +
  scale_y_reverse(limits = c(1200,0)) +
  theme_bw()

Group Averages With Smoothing

So I’ll back up and smooth each person’s data using a moving average window of span = 5. Taken from our adult manuscript which had this:

The data were then smoothed with a standard moving average noise reduction algorithm (window size = 5 samples) which acts as a low-pass filter that reduces the influence of microsaccades, blinks, and large data gaps (based on Yarbus, 1967).

The below chart shows Adam’s data, blue is unsmoothed and red is smoothed.

data <- data %>%
  group_by(maingroup, recording_name) %>%
  mutate(y_ma = RcppRoll::roll_mean(y, n = 5, fill = 0))
data %>%
  filter(recording_name == "Adam_Good") %>%
  ggplot() +
  geom_line(aes(x = gaze_point_index, y = y), color = "blue", alpha = 0.25, size = 0.5) +
  geom_line(aes(x = gaze_point_index, y = y_ma), color = "red", size = 0.2) +
  scale_y_reverse(limits = c(475, 325)) +
  theme_bw()

So that’s nice. Let’s go do group averages again.

averaged_y <- data %>%
  group_by(maingroup, gaze_point_index) %>%
  summarise(y_mean = mean(y_ma, na.rm = T),
            y_sd = sd(y_ma, na.rm = T),
            y_count = n(),
            y_se = y_sd/sqrt(y_count))
averaged_y %>%
  ggplot() + 
  geom_line(aes(x = gaze_point_index, y = y_mean, color = maingroup)) +
  geom_ribbon(aes(x = gaze_point_index, 
                  ymin = y_mean-y_se, 
                  ymax = y_mean+y_se,
                  fill = maingroup), alpha = 0.5) +
  scale_y_reverse(limits = c(1200,0)) +
  theme_bw() +
  facet_wrap("maingroup")

averaged_y %>%
  ggplot() + 
  geom_line(aes(x = gaze_point_index, y = y_mean, color = maingroup)) +
  geom_ribbon(aes(x = gaze_point_index, 
                  ymin = y_mean-y_se, 
                  ymax = y_mean+y_se,
                  fill = maingroup), alpha = 0.5) +
  scale_y_reverse(limits = c(1200,0)) +
  theme_bw()

averaged_y %>%
  filter(maingroup == "DeafEarly" | maingroup == "HearingNovice") %>%
  ggplot() + 
  geom_line(aes(x = gaze_point_index, y = y_mean, color = maingroup)) +
  geom_ribbon(aes(x = gaze_point_index, 
                  ymin = y_mean-y_se, 
                  ymax = y_mean+y_se,
                  fill = maingroup), alpha = 0.5) +
  scale_y_reverse(limits = c(700,300)) +
  theme_bw()

Group Averages With More Smoothing

Maybe we should smooth even more. Sample size = 10!

data <- data %>%
  group_by(maingroup, recording_name) %>%
  mutate(y_ma2 = RcppRoll::roll_mean(y, n = 10, fill = 0))
Grouping rowwise data frame strips rowwise nature
# data %>%
#   filter(recording_name == "Adam_Good") %>%
#   ggplot() +
#   geom_line(aes(x = gaze_point_index, y = y), color = "blue", alpha = 0.25, size = 0.5) +
#   geom_line(aes(x = gaze_point_index, y = y_ma2), color = "red", size = 0.2) +
#   scale_y_reverse(limits = c(475, 325)) +
#   theme_bw()
averaged_y <- data %>%
  group_by(maingroup, gaze_point_index) %>%
  summarise(y_mean = mean(y_ma2, na.rm = T),
            y_sd = sd(y_ma2, na.rm = T),
            y_count = n(),
            y_se = y_sd/sqrt(y_count))
library(hrbrthemes)
averaged_y %>%
  ggplot() + 
  geom_line(aes(x = gaze_point_index, y = y_mean, color = maingroup), size = 0.8) +
  geom_ribbon(aes(x = gaze_point_index, 
                  ymin = y_mean-y_se, 
                  ymax = y_mean+y_se,
                  fill = maingroup), alpha = 0.5) +
  scale_y_reverse(limits = c(1200,0)) +
  facet_wrap("maingroup") +
  labs(x = "time (ms)", y = "pixels", title = "Figure 1. Vertical Eye Gaze Position Across One ASL Narrative") +
  guides(color = F, fill = F) +
  theme_ipsum_rc()

averaged_y %>%
  ggplot() + 
  geom_line(aes(x = gaze_point_index, y = y_mean, color = maingroup)) +
  geom_ribbon(aes(x = gaze_point_index, 
                  ymin = y_mean-y_se, 
                  ymax = y_mean+y_se,
                  fill = maingroup), alpha = 0.5) +
  scale_y_reverse(limits = c(1200,0)) +
  theme_bw()

averaged_y %>%
  filter(maingroup == "DeafEarly" | maingroup == "HearingNovice") %>%
  ggplot() + 
  geom_line(aes(x = gaze_point_index, y = y_mean, color = maingroup), size = 0.8) +
  geom_ribbon(aes(x = gaze_point_index, 
                  ymin = y_mean-y_se, 
                  ymax = y_mean+y_se,
                  fill = maingroup), alpha = 0.1) +
  scale_y_reverse(limits = c(700,300)) +
  labs(x = "time (ms)", y = "pixels", title = "Figure 2. Deaf Early Signers vs. Hearing Novice Signers", color = "", fill = "") +
  theme_ipsum_rc()

Everything Else That Was Already Here

Next let’s plot the moments where spatial referencing happens. Those are frames

  1. 198 to 223
  2. 265 to 288
  3. 352 to 380

The max gazepointindex is around 2580. At 120 Hz, that’s 21.5 seconds which is just right, that’s the length. Let’s go ahead and convert gazepointindex to seconds.

So we just have to convert frames to gazepointindex. The video is a total of 536 frames, at 25 FPS that’s 21.5 seconds. 535/25 = 21.5, so we divide all those frames by 25.

  1. 7.92s to 8.92s
  2. 10.6s to 11.52s
  3. 14.08s to 15.2s

And plot those!

data <- data %>%
  rowwise() %>%
  mutate(secs = gaze_point_index/120)
data %>%
  ggplot(aes(x = secs, y = y, color = maingroup, group = name)) + 
  scale_y_reverse() + 
  geom_line() + 
  annotate("rect", xmin = 7.92, xmax = 8.92, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 10.6, xmax = 11.52, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 14.08, xmax = 15.2, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  theme_bw()

Maybe easier if we separate groups of signers.

data %>%
  ggplot(aes(x = secs, y = y, color = maingroup, group = name)) + 
  scale_y_reverse() + 
  geom_line(alpha = 0.5) + 
  annotate("rect", xmin = 7.92, xmax = 8.92, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 10.6, xmax = 11.52, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 14.08, xmax = 15.2, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  facet_grid(maingroup ~ .) +
  theme_bw() +
  guides(color = FALSE)

Next, we’re going to add AOI position information. We’re going to pull in information on signers’ right hand position (and then apply the same idea to other body parts). I successfully wrote a function called get_xy_timestamp to do this! Yay. I’m chuffed, as the British would say.

Let’s try this on Stephanie’s data. Let’s see if we can find a correlation between any of those and the eye gaze y-position.

# We add one more row to the xy_timestamp data to align it with the end of the eye gaze data.
rhand <- get_xy_timestamp("aoi_position/Cindy_bears_FW_Position of Right Hand.txt") %>%
  add_row(sec = 21.5, x = 640.16, y = 1055.97)
lhand <- get_xy_timestamp("aoi_position/Cindy_bears_FW_Position of Left Hand.txt") %>%
  add_row(sec = 21.5, x = 703.74, y = 1058.39)
mouth <- get_xy_timestamp("aoi_position/Cindy_bears_FW_Position of mouth small.txt") %>%
  add_row(sec = 21.5, x = 656.37, y = 373.99)
# Get Stephanie's data
steph <- filter(data, name == "Stephanie")
steph %>%
  ggplot(aes(x = secs, y = y)) + 
  scale_y_reverse(limits = c(1200,0), expand = c(0,0)) + 
  geom_line(alpha = 1, color = "purple") + 
  # annotate("rect", xmin = 7.92, xmax = 8.92, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
  # annotate("rect", xmin = 10.6, xmax = 11.52, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
  # annotate("rect", xmin = 14.08, xmax = 15.2, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
  # geom_step(data = rhand, aes(x = sec, y = y), color = "red", linetype = "longdash", alpha = 0.5) + 
  # geom_step(data = lhand, aes(x = sec, y = y), color = "blue", linetype = "longdash", alpha = 0.5) + 
  # geom_step(data = mouth, aes(x = sec, y = y), color = "black", linetype = "longdash", alpha = 0.5) + 
  # annotate("text", label = "Right Hand", x = 3, y = 1000, color = "red", alpha = 0.5) +
  # annotate("text", label = "Left Hand", x = 3, y = 1100, color = "blue", alpha = 0.5) +
  # annotate("text", label = "Mouth", x = 3, y = 200, color = "black", alpha = 0.5) +
  ggtitle("Stephanie") +
  theme_bw() +
  theme(panel.grid.minor.y = element_blank())

steph %>%
  ggplot(aes(x = secs, y = y)) + 
  scale_y_reverse(limits = c(1200,0), expand = c(0,0)) + 
  geom_line(alpha = 1, color = "purple") + 
  # annotate("rect", xmin = 7.92, xmax = 8.92, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
  # annotate("rect", xmin = 10.6, xmax = 11.52, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
  # annotate("rect", xmin = 14.08, xmax = 15.2, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
#  geom_step(data = rhand, aes(x = sec, y = y), color = "red", linetype = "longdash", alpha = 0.5) + 
#  geom_step(data = lhand, aes(x = sec, y = y), color = "blue", linetype = "longdash", alpha = 0.5) + 
  geom_step(data = mouth, aes(x = sec, y = y), color = "black", linetype = "longdash", alpha = 0.5) + 
# annotate("text", label = "Right Hand", x = 3, y = 1000, color = "red", alpha = 0.5) +
#  annotate("text", label = "Left Hand", x = 3, y = 1100, color = "blue", alpha = 0.5) +
  annotate("text", label = "Mouth", x = 3, y = 250, color = "black", alpha = 0.5) +
  ggtitle("Stephanie") +
  theme_bw() +
  theme(panel.grid.minor.y = element_blank())

steph %>%
  ggplot(aes(x = secs, y = y)) + 
  scale_y_reverse(limits = c(1200,0), expand = c(0,0)) + 
  geom_line(alpha = 1, color = "purple") + 
  # annotate("rect", xmin = 7.92, xmax = 8.92, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
  # annotate("rect", xmin = 10.6, xmax = 11.52, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
  # annotate("rect", xmin = 14.08, xmax = 15.2, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
  geom_step(data = rhand, aes(x = sec, y = y), color = "red", linetype = "longdash", alpha = 0.5) + 
#  geom_step(data = lhand, aes(x = sec, y = y), color = "blue", linetype = "longdash", alpha = 0.5) + 
  geom_step(data = mouth, aes(x = sec, y = y), color = "black", linetype = "longdash", alpha = 0.5) + 
  annotate("text", label = "Right Hand", x = 3, y = 1000, color = "red", alpha = 0.5) +
#  annotate("text", label = "Left Hand", x = 3, y = 1100, color = "blue", alpha = 0.5) +
  annotate("text", label = "Mouth", x = 3, y = 250, color = "black", alpha = 0.5) +
  ggtitle("Stephanie") +
  theme_bw() +
  theme(panel.grid.minor.y = element_blank())

steph %>%
  ggplot(aes(x = secs, y = y)) + 
  scale_y_reverse(limits = c(1200,0), expand = c(0,0)) + 
  geom_line(alpha = 1, color = "purple") + 
  # annotate("rect", xmin = 7.92, xmax = 8.92, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
  # annotate("rect", xmin = 10.6, xmax = 11.52, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
  # annotate("rect", xmin = 14.08, xmax = 15.2, ymin = 0, ymax = 1200,
  # alpha = .2, fill = "red") +
  geom_step(data = rhand, aes(x = sec, y = y), color = "red", linetype = "longdash", alpha = 0.5) + 
  geom_step(data = lhand, aes(x = sec, y = y), color = "blue", linetype = "longdash", alpha = 0.5) + 
  geom_step(data = mouth, aes(x = sec, y = y), color = "black", linetype = "longdash", alpha = 0.5) + 
  annotate("text", label = "Right Hand", x = 3, y = 1000, color = "red", alpha = 0.5) +
  annotate("text", label = "Left Hand", x = 3, y = 1100, color = "blue", alpha = 0.5) +
  annotate("text", label = "Mouth", x = 3, y = 250, color = "black", alpha = 0.5) +
  ggtitle("Stephanie") +
  theme_bw() +
  theme(panel.grid.minor.y = element_blank())

Now let’s work on correlations. First, our AOI vectors are not the same size as our eye gaze vectors, and the x/y position is irregularly spaced across time (irregularly spaced key frames).

# The following code will "expand" the rhand data vectors to fit the length of Stephanie's data vectors.
time_index <- steph$secs
closest <- function(x){
  which.min(abs(time_index-x))
}
index_loc <- map_int(rhand$sec, closest)
rhand <- cbind(rhand, time_index[index_loc]) %>%
  select(-sec) %>%
  rename(sec = "time_index[index_loc]") %>%
  select(sec, x, y)
rhand_full <- select(steph, secs) %>%
  rename(sec = secs) %>%
  left_join(rhand) %>%
  fill(x) %>%
  fill(y) %>%
  slice(1:(nrow(.)-1))
Joining, by = "sec"
rhand_full <- rhand_full %>%
  filter(sec < rhand$sec[172]) %>%
  filter(sec >= rhand$sec[2])
steph <- steph %>%
  filter(secs < rhand$sec[172]) %>%
  filter(secs >= rhand$sec[2])
a <- rhand_full$y
a <- a[1:length(a)-1] # Shorten it by one element
b <- steph$y
# Then run correlations
cor(a,b, use = "complete.obs") # basic correlation
[1] 0.2894728
that <- ccf(a,b, lag.max = 400, type = "correlation", na.action = na.pass, plot = T) # auto-correlation

Let’s separate out individual signers.

make_signer_plots <- function(groupname, line_color) {
  data %>%
  filter(maingroup == groupname) %>%
  ggplot(aes(x = secs, y = y)) + 
  scale_y_reverse() + 
  geom_line(alpha = 1, color = line_color) + 
  annotate("rect", xmin = 7.92, xmax = 8.92, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 10.6, xmax = 11.52, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 14.08, xmax = 15.2, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  geom_step(data = rhand, aes(x = sec, y = y), color = "red", linetype = "longdash", alpha = 0.5) + 
  geom_step(data = lhand, aes(x = sec, y = y), color = "blue", linetype = "longdash", alpha = 0.5) + 
  geom_step(data = mouth, aes(x = sec, y = y), color = "black", linetype = "longdash", alpha = 0.5) + 
  annotate("text", label = "Right Hand", x = 3, y = 1000, color = "red", alpha = 0.5) +
  annotate("text", label = "Left Hand", x = 3, y = 1100, color = "blue", alpha = 0.5) +
  annotate("text", label = "Mouth", x = 3, y = 200, color = "black", alpha = 0.5) +
  facet_grid(name ~ .) +
  ggtitle(groupname) +
  theme_bw()
}
make_signer_plots("DeafEarly", "red")

make_signer_plots("DeafLate", "dark green")

make_signer_plots("HearingLate", "blue")

make_signer_plots("HearingNovice", "purple")

Okay so with Early ASL obviously very steady gaze. NoviceASL has lot of downshifts. Some align with spatial referencing, some do not. We need more of them (let’s look at other stories w better data).

Midas Forward

# Get Midas data
data <- read_csv("../Adult Data/rawdata/midasfw.csv") %>%
  clean_names() %>%
  rename(y = gaze_point_y_mc_spx,
         language = language_value,
         name = participant_name,
         group = group_value)
# Pull clean names and join to data
cleannames <- read_csv("partnames.csv") %>%
  distinct() %>%
  rename(name = participant)
data <- data %>% left_join(cleannames, by = "name") %>%
  select(-name) %>%
  rename(name = new_participant) %>%
  filter(!is.na(name))
# Pull final group assignments and join to data
cleangroups <- read_csv("finaldataset.csv") %>%
  select(participant, maingroup) %>%
  rename(name = participant) %>%
  distinct()
data <- data %>% left_join(cleangroups, by = "name") %>%
  select(-group)
# Let's find out who was NOT included in Three Bears
excluded <- read_csv("finaldataset.csv") %>%
  select(participant, maingroup, story, direction, eye_exclude) %>%
  filter(story == "KingMidas" & direction == "forward") %>%
  rename(name = participant) %>%
  select(name, eye_exclude)
data <- data %>% left_join(excluded, by = "name") %>%
  filter(!eye_exclude) %>%
  filter(!is.na(eye_exclude))
data %>% select(name, maingroup) %>% distinct()

Now let’s graph!!

Hm. One person seems wrong.

data %>%
  ggplot(aes(x = gaze_point_index, y = y, color = maingroup, group = name)) + geom_line() + scale_y_reverse()

Okay it’s Jesse’s data that seems off. We’ll remove him for now and come back to it, figure out why.

data %>% filter(gaze_point_index > 30000) %>% select(name) %>% distinct() %>% head()
data <- data %>%
  filter(name != "Jesse")
data %>%
  ggplot(aes(x = gaze_point_index, y = y, color = maingroup, group = name)) + geom_line() + 
  scale_y_reverse() +
  scale_x_continuous(limits = c(0,4500))

Next let’s plot the moments where spatial referencing happens. Those are frames

  1. 248 to 427
  2. 460 to 508
  3. 512 to 560

Like before, we’ll convert gazepointindex to seconds (by dividing 120) and all frames to seconds (by dividing 25).

  1. 9.92s to 17.08s
  2. 18.4s to 20.32s
  3. 20.48s to 22.4s
data <- data %>%
  rowwise() %>%
  mutate(secs = gaze_point_index/120)
data %>%
  ggplot(aes(x = secs, y = y, color = maingroup, group = name)) + 
  scale_y_reverse() + 
  scale_x_continuous(limits = c(0, 37.5)) +
  geom_line() + 
  annotate("rect", xmin = 9.92, xmax = 17.08, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 18.4, xmax = 20.32, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 20.48, xmax = 22.4, ymin = 0, ymax = 900,
  alpha = .2, fill = "red")

Maybe easier if we separate groups of signers.

data %>%
  ggplot(aes(x = secs, y = y, color = maingroup, group = name)) + 
  scale_y_reverse() + 
  scale_x_continuous(limits = c(0, 37.5)) +
  geom_line(alpha = 0.5) + 
  annotate("rect", xmin = 9.92, xmax = 17.08, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 18.4, xmax = 20.32, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 20.48, xmax = 22.4, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  facet_grid(maingroup ~ .)

Individual signers.

data %>%
  filter(maingroup == "DeafEarly") %>%
  ggplot(aes(x = secs, y = y, group = name)) + 
  scale_x_continuous(limits = c(0, 37.5)) +
  scale_y_reverse() + 
  geom_line(alpha = 1, color = "red") + 
  annotate("rect", xmin = 9.92, xmax = 17.08, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 18.4, xmax = 20.32, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 20.48, xmax = 22.4, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  facet_grid(name ~ .) +
  ggtitle("DeafEarly")

data %>%
  filter(maingroup == "DeafLate") %>%
  ggplot(aes(x = secs, y = y, group = name)) + 
  scale_y_reverse() + 
  scale_x_continuous(limits = c(0, 37.5)) +
  geom_line(alpha = 1, color = "dark green") + 
  annotate("rect", xmin = 9.92, xmax = 17.08, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 18.4, xmax = 20.32, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 20.48, xmax = 22.4, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  facet_grid(name ~ .) +
  ggtitle("DeafLate")

data %>%
  filter(maingroup == "HearingLate") %>%
  ggplot(aes(x = secs, y = y, group = name)) + 
  scale_y_reverse() + 
  scale_x_continuous(limits = c(0, 37.5)) +
  geom_line(alpha = 1, color = "blue") + 
  annotate("rect", xmin = 9.92, xmax = 17.08, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 18.4, xmax = 20.32, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 20.48, xmax = 22.4, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  facet_grid(name ~ .) +
  ggtitle("HearingLate")

data %>%
  filter(maingroup == "HearingNovice") %>%
  ggplot(aes(x = secs, y = y, group = name)) + 
  scale_y_reverse() + 
  scale_x_continuous(limits = c(0, 37.5)) +
  geom_line(alpha = 1, color = "purple") + 
  annotate("rect", xmin = 9.92, xmax = 17.08, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 18.4, xmax = 20.32, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  annotate("rect", xmin = 20.48, xmax = 22.4, ymin = 0, ymax = 900,
  alpha = .2, fill = "red") +
  facet_grid(name ~ .) +
  ggtitle("HearingNovice")

LS0tCnRpdGxlOiAiU3BhdGlhbCBSZWZlcmVuY2luZyIKYXV0aG9yOiAiQWRhbSBTdG9uZSwgUGhEIgpkYXRlOiAnYHIgZm9ybWF0KFN5cy5EYXRlKCksICIlbS0lZC0lWSIpYCcKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIHRoZW1lOiBwYXBlcgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogMgogICAgdG9jX2Zsb2F0OiB5ZXMKLS0tCgpgYGB7cn0KIyMgUmVhZHMgaW4gQU9JIHBvc2l0aW9uIHRleHQgZmlsZXMgZnJvbSBUb2lpCiMjIFdpbGwgcmV0dXJuIHRpYmJsZSBvZiBjb2x1bW5zIHNlYywgeCwgeSwgd2l0aCByb3dzIGZvciBlYWNoIHRpbWVzdGFtcC9BT0kgcG9zaXRpb24KCmdldF94eV90aW1lc3RhbXAgPC0gZnVuY3Rpb24oeil7Cgp4IDwtIHJlYWRfbGluZXMoeikgJT4lCiAgYXNfdGliYmxlKCkgJT4lCiAgcm93aWRfdG9fY29sdW1uKCJJRCIpCgojIHB1bGwgb3V0IHRpbWVzdGFtcCByb3dzCnRpbWVzdGFtcHMgPC0geCAlPiUKICBmaWx0ZXIoc3RyX2RldGVjdCh2YWx1ZSwgInRpbWVzdGFtcCIpKSAlPiUKICBzZXBhcmF0ZSh2YWx1ZSwgaW50byA9IGMoInRocm93IiwidGltZXN0YW1wIiksIHNlcCA9ICIgPSAiKSAlPiUKICBzZXBhcmF0ZSh0aW1lc3RhbXAsIGludG8gPSBjKCJvbmUiLCJ0d28iLCJzZWMiKSwgc2VwID0gIjoiKSAlPiUKICBzZWxlY3Qoc2VjKSAlPiUKICBtdXRhdGUoc2VjID0gYXMubnVtZXJpYyhzZWMpKQoKIyBGaW5kIEFPSSBjb29yZGluYXRlIHJvd3MKeHlzIDwtIHggJT4lCiAgbXV0YXRlKGZpbmQgPSBzdHJfZGV0ZWN0KHZhbHVlLCAiWFx0WSIpKQoKIyBmaXJzdCB2ZXJ0ZXggKDIgcm93cyBhZnRlciBlYWNoICJYWSIgbGluZSkKeHlzX3JvdyA8LSB3aGljaCh4eXMkZmluZCkgKyAyCgp4eTEgPC0geCAlPiUKICBmaWx0ZXIoSUQgJWluJSB4eXNfcm93KSAlPiUKICBzZXBhcmF0ZSh2YWx1ZSwgaW50byA9IGMoIngxIiwieTEiKSwgc2VwID0gIlx0IikgJT4lCiAgc2VsZWN0KC1JRCkKCiMgb3Bwb3NpdGUgdmVydGV4ICgyIG1vcmUgcm93cyBkb3duKQp4eXNfcm93IDwtIHh5c19yb3cgKyAyCgp4eTIgPC0geCAlPiUKICBmaWx0ZXIoSUQgJWluJSB4eXNfcm93KSAlPiUKICBzZXBhcmF0ZSh2YWx1ZSwgaW50byA9IGMoIngyIiwieTIiKSwgc2VwID0gIlx0IikgJT4lCiAgc2VsZWN0KC1JRCkKCiMgTm93IGdldCBhdmVyYWdlIFhZIHBvc2l0aW9uIHBlciB0aW1lc3RhbXAKeHlzIDwtIGNiaW5kKHRpbWVzdGFtcHMsIHh5MSwgeHkyKSAlPiUKICBtdXRhdGVfYWxsKGFzLm51bWVyaWMpICU+JQogIHJvd3dpc2UoKSAlPiUKICBtdXRhdGUoeCA9IG1lYW4oeDEseDIpLAogICAgICAgICB5ID0gbWVhbih5MSwgeTIpKSAlPiUKICBzZWxlY3Qoc2VjLCB4LCB5KQp9CmBgYAoKTGV0J3MgZ2l2ZSB0aGlzIGEgc2hvdCEhCgojIFRocmVlIEJlYXJzIEZvcndhcmQgCkZpcnN0IGxldCdzIHNlZSB3aG8ncyBpbiBvdXIgZGF0YXNldC4gVGhpcyBpcyBUZXN0IDEgLSAzIEJlYXJzIC0gRm9yd2FyZC4gV2UncmUgcHVsbGluZyBjbGVhbmVkLXVwIG5hbWVzIGFuZCBhc3NpZ25lZCBncm91cHMgZnJvbSBvdXIgZmluYWwgZGF0YXNldCB0aGF0IHdlIHVzZWQgaW4gb3VyIEFPSSBhbmFseXNpcy4gVGhlbiB3ZSBhcmUgcmVtb3ZpbmcgcGFydGljaXBhbnRzIHdob3NlIFRocmVlIEJlYXJzIEZvcndhcmQgc3Rvcnkgd2Fzbid0IGluY2x1ZGVkIGluIG91ciBBT0kgYW5hbHlzaXMgZHVlIHRvIDwyNSUgbG9va2luZyB0aW1lIG9yIG90aGVyIHJlYXNvbnMuIAoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkob3Blbnhsc3gpCmxpYnJhcnkoamFuaXRvcikKCiMgR2V0IFRocmVlIEJlYXJzIGRhdGEKZGF0YSA8LSByZWFkLnhsc3goIlRlc3QxX0NpbmR5X2JlYXJzX0ZXX0V4YW1pbmUgZm9yIFNwYXRpYWwgUmVmZXJlbmNpbmcueGxzeCIpICU+JQogIGNsZWFuX25hbWVzKCkgJT4lCiAgcmVuYW1lKHkgPSBnYXplX3BvaW50X3lfbWNfc3B4LAogICAgICAgICBsYW5ndWFnZSA9IGxhbmd1YWdlX3ZhbHVlLAogICAgICAgICBuYW1lID0gcGFydGljaXBhbnRfbmFtZSwKICAgICAgICAgZ3JvdXAgPSBncm91cF92YWx1ZSkKCiMgUHVsbCBjbGVhbiBuYW1lcyBhbmQgam9pbiB0byBkYXRhIChhbmQgYWRkIExhdXJhMiBmb3IgTGF1cmEgKG1pc3Npbmcgc3RvcmllcykpCmNsZWFubmFtZXMgPC0gcmVhZF9jc3YoInBhcnRuYW1lcy5jc3YiKSAlPiUKICBkaXN0aW5jdCgpICU+JQogIHJlbmFtZShuYW1lID0gcGFydGljaXBhbnQpICU+JQogIGZpbHRlcihuYW1lICE9ICJMYXVyYTIiKQoKZGF0YSA8LSBkYXRhICU+JSAKICBsZWZ0X2pvaW4oY2xlYW5uYW1lcywgYnkgPSAibmFtZSIpICU+JQogIHNlbGVjdCgtbmFtZSkgJT4lCiAgcmVuYW1lKG5hbWUgPSBuZXdfcGFydGljaXBhbnQpICU+JQogIGZpbHRlcighaXMubmEobmFtZSkpCgojIFB1bGwgZmluYWwgZ3JvdXAgYXNzaWdubWVudHMgYW5kIGpvaW4gdG8gZGF0YQpjbGVhbmdyb3VwcyA8LSByZWFkX2NzdigiZmluYWxkYXRhc2V0LmNzdiIpICU+JQogIHNlbGVjdChwYXJ0aWNpcGFudCwgbWFpbmdyb3VwKSAlPiUKICByZW5hbWUobmFtZSA9IHBhcnRpY2lwYW50KSAlPiUKICBkaXN0aW5jdCgpCgpkYXRhIDwtIGRhdGEgJT4lIGxlZnRfam9pbihjbGVhbmdyb3VwcywgYnkgPSAibmFtZSIpICU+JQogIHNlbGVjdCgtZ3JvdXApCgojIExldCdzIGZpbmQgb3V0IHdobyB3YXMgTk9UIGluY2x1ZGVkIGluIFRocmVlIEJlYXJzCmV4Y2x1ZGVkIDwtIHJlYWRfY3N2KCJmaW5hbGRhdGFzZXQuY3N2IikgJT4lCiAgc2VsZWN0KHBhcnRpY2lwYW50LCBtYWluZ3JvdXAsIHN0b3J5LCBkaXJlY3Rpb24sIGV5ZV9leGNsdWRlKSAlPiUKICBmaWx0ZXIoc3RvcnkgPT0gIkdvbGRpbG9ja3MiICYgZGlyZWN0aW9uID09ICJmb3J3YXJkIikgJT4lCiAgcmVuYW1lKG5hbWUgPSBwYXJ0aWNpcGFudCkgJT4lCiAgc2VsZWN0KG5hbWUsIGV5ZV9leGNsdWRlKQoKZGF0YSA8LSBkYXRhICU+JSBsZWZ0X2pvaW4oZXhjbHVkZWQsIGJ5ID0gIm5hbWUiKSAlPiUKICBmaWx0ZXIoIWV5ZV9leGNsdWRlKSAlPiUKICBmaWx0ZXIoIWlzLm5hKGV5ZV9leGNsdWRlKSkKCmRhdGEgJT4lIHNlbGVjdChuYW1lLCBtYWluZ3JvdXApICU+JSBkaXN0aW5jdCgpCmBgYAoKTm93IGxldCdzIGdyYXBoISEgCgpNZXNzeSwgSSBrbm93LCBidXQgYWxyZWFkeSB3ZSBjYW4gc2VlIHNvbWUgSGVhcmluZ05vdmljZSBoYXMgYmlnIHNoaWZ0cyBkb3dud2FyZC4gQW5kIHNvbWUgSGVhcmluZ0xhdGUgdG9vLgoKYGBge3J9CmRhdGEgJT4lCiAgZ2dwbG90KGFlcyh4ID0gZ2F6ZV9wb2ludF9pbmRleCwgeSA9IHksIGNvbG9yID0gbWFpbmdyb3VwLCBncm91cCA9IG5hbWUpKSArIGdlb21fbGluZSgpICsgCiAgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTIwMCwwKSkgKwogIHRoZW1lX2J3KCkKYGBgCgojIEdyb3VwIEF2ZXJhZ2VzCgpOZXh0LCBsZXQncyBtYWtlIGdyb3VwIGF2ZXJhZ2VzLiAKCmBgYHtyfQphdmVyYWdlZF95IDwtIGRhdGEgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLCBnYXplX3BvaW50X2luZGV4KSAlPiUKICBzdW1tYXJpc2UoeV9tZWFuID0gbWVhbih5LCBuYS5ybSA9IFQpLAogICAgICAgICAgICB5X3NkID0gc2QoeSwgbmEucm0gPSBUKSwKICAgICAgICAgICAgeV9jb3VudCA9IG4oKSwKICAgICAgICAgICAgeV9zZSA9IHlfc2Qvc3FydCh5X2NvdW50KSkKCmF2ZXJhZ2VkX3kgJT4lCiAgZ2dwbG90KCkgKyAKICBnZW9tX2xpbmUoYWVzKHggPSBnYXplX3BvaW50X2luZGV4LCB5ID0geV9tZWFuLCBjb2xvciA9IG1haW5ncm91cCkpICsKICBnZW9tX3JpYmJvbihhZXMoeCA9IGdhemVfcG9pbnRfaW5kZXgsIAogICAgICAgICAgICAgICAgICB5bWluID0geV9tZWFuLXlfc2UsIAogICAgICAgICAgICAgICAgICB5bWF4ID0geV9tZWFuK3lfc2UsCiAgICAgICAgICAgICAgICAgIGZpbGwgPSBtYWluZ3JvdXApLCBhbHBoYSA9IDAuNSkgKwogIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEyMDAsMCkpICsKICB0aGVtZV9idygpICsKICBmYWNldF93cmFwKCJtYWluZ3JvdXAiKQoKYXZlcmFnZWRfeSAlPiUKICBnZ3Bsb3QoKSArIAogIGdlb21fbGluZShhZXMoeCA9IGdhemVfcG9pbnRfaW5kZXgsIHkgPSB5X21lYW4sIGNvbG9yID0gbWFpbmdyb3VwKSkgKwogIGdlb21fcmliYm9uKGFlcyh4ID0gZ2F6ZV9wb2ludF9pbmRleCwgCiAgICAgICAgICAgICAgICAgIHltaW4gPSB5X21lYW4teV9zZSwgCiAgICAgICAgICAgICAgICAgIHltYXggPSB5X21lYW4reV9zZSwKICAgICAgICAgICAgICAgICAgZmlsbCA9IG1haW5ncm91cCksIGFscGhhID0gMC41KSArCiAgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTIwMCwwKSkgKwogIHRoZW1lX2J3KCkKYGBgCgojIEdyb3VwIEF2ZXJhZ2VzIFdpdGggU21vb3RoaW5nCgpTbyBJJ2xsIGJhY2sgdXAgYW5kIHNtb290aCBlYWNoIHBlcnNvbidzIGRhdGEgdXNpbmcgYSBtb3ZpbmcgYXZlcmFnZSB3aW5kb3cgb2Ygc3BhbiA9IDUuIFRha2VuIGZyb20gb3VyIGFkdWx0IG1hbnVzY3JpcHQgd2hpY2ggaGFkIHRoaXM6IAoKPiBUaGUgZGF0YSB3ZXJlIHRoZW4gc21vb3RoZWQgd2l0aCBhIHN0YW5kYXJkIG1vdmluZyBhdmVyYWdlIG5vaXNlIHJlZHVjdGlvbiBhbGdvcml0aG0gKHdpbmRvdyBzaXplID0gNSBzYW1wbGVzKSB3aGljaCBhY3RzIGFzIGEgbG93LXBhc3MgZmlsdGVyIHRoYXQgcmVkdWNlcyB0aGUgaW5mbHVlbmNlIG9mIG1pY3Jvc2FjY2FkZXMsIGJsaW5rcywgYW5kIGxhcmdlIGRhdGEgZ2FwcyAoYmFzZWQgb24gWWFyYnVzLCAxOTY3KS4gCgpUaGUgYmVsb3cgY2hhcnQgc2hvd3MgQWRhbSdzIGRhdGEsIGJsdWUgaXMgdW5zbW9vdGhlZCBhbmQgcmVkIGlzIHNtb290aGVkLiAKCgpgYGB7cn0KZGF0YSA8LSBkYXRhICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCwgcmVjb3JkaW5nX25hbWUpICU+JQogIG11dGF0ZSh5X21hID0gUmNwcFJvbGw6OnJvbGxfbWVhbih5LCBuID0gNSwgZmlsbCA9IDApKQoKZGF0YSAlPiUKICBmaWx0ZXIocmVjb3JkaW5nX25hbWUgPT0gIkFkYW1fR29vZCIpICU+JQogIGdncGxvdCgpICsKICBnZW9tX2xpbmUoYWVzKHggPSBnYXplX3BvaW50X2luZGV4LCB5ID0geSksIGNvbG9yID0gImJsdWUiLCBhbHBoYSA9IDAuMjUsIHNpemUgPSAwLjUpICsKICBnZW9tX2xpbmUoYWVzKHggPSBnYXplX3BvaW50X2luZGV4LCB5ID0geV9tYSksIGNvbG9yID0gInJlZCIsIHNpemUgPSAwLjIpICsKICBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYyg0NzUsIDMyNSkpICsKICB0aGVtZV9idygpCmBgYAoKU28gdGhhdCdzIG5pY2UuIExldCdzIGdvIGRvIGdyb3VwIGF2ZXJhZ2VzIGFnYWluLiAKCmBgYHtyfQphdmVyYWdlZF95IDwtIGRhdGEgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLCBnYXplX3BvaW50X2luZGV4KSAlPiUKICBzdW1tYXJpc2UoeV9tZWFuID0gbWVhbih5X21hLCBuYS5ybSA9IFQpLAogICAgICAgICAgICB5X3NkID0gc2QoeV9tYSwgbmEucm0gPSBUKSwKICAgICAgICAgICAgeV9jb3VudCA9IG4oKSwKICAgICAgICAgICAgeV9zZSA9IHlfc2Qvc3FydCh5X2NvdW50KSkKCmF2ZXJhZ2VkX3kgJT4lCiAgZ2dwbG90KCkgKyAKICBnZW9tX2xpbmUoYWVzKHggPSBnYXplX3BvaW50X2luZGV4LCB5ID0geV9tZWFuLCBjb2xvciA9IG1haW5ncm91cCkpICsKICBnZW9tX3JpYmJvbihhZXMoeCA9IGdhemVfcG9pbnRfaW5kZXgsIAogICAgICAgICAgICAgICAgICB5bWluID0geV9tZWFuLXlfc2UsIAogICAgICAgICAgICAgICAgICB5bWF4ID0geV9tZWFuK3lfc2UsCiAgICAgICAgICAgICAgICAgIGZpbGwgPSBtYWluZ3JvdXApLCBhbHBoYSA9IDAuNSkgKwogIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDEyMDAsMCkpICsKICB0aGVtZV9idygpICsKICBmYWNldF93cmFwKCJtYWluZ3JvdXAiKQoKYXZlcmFnZWRfeSAlPiUKICBnZ3Bsb3QoKSArIAogIGdlb21fbGluZShhZXMoeCA9IGdhemVfcG9pbnRfaW5kZXgsIHkgPSB5X21lYW4sIGNvbG9yID0gbWFpbmdyb3VwKSkgKwogIGdlb21fcmliYm9uKGFlcyh4ID0gZ2F6ZV9wb2ludF9pbmRleCwgCiAgICAgICAgICAgICAgICAgIHltaW4gPSB5X21lYW4teV9zZSwgCiAgICAgICAgICAgICAgICAgIHltYXggPSB5X21lYW4reV9zZSwKICAgICAgICAgICAgICAgICAgZmlsbCA9IG1haW5ncm91cCksIGFscGhhID0gMC41KSArCiAgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTIwMCwwKSkgKwogIHRoZW1lX2J3KCkKCmF2ZXJhZ2VkX3kgJT4lCiAgZmlsdGVyKG1haW5ncm91cCA9PSAiRGVhZkVhcmx5IiB8IG1haW5ncm91cCA9PSAiSGVhcmluZ05vdmljZSIpICU+JQogIGdncGxvdCgpICsgCiAgZ2VvbV9saW5lKGFlcyh4ID0gZ2F6ZV9wb2ludF9pbmRleCwgeSA9IHlfbWVhbiwgY29sb3IgPSBtYWluZ3JvdXApKSArCiAgZ2VvbV9yaWJib24oYWVzKHggPSBnYXplX3BvaW50X2luZGV4LCAKICAgICAgICAgICAgICAgICAgeW1pbiA9IHlfbWVhbi15X3NlLCAKICAgICAgICAgICAgICAgICAgeW1heCA9IHlfbWVhbit5X3NlLAogICAgICAgICAgICAgICAgICBmaWxsID0gbWFpbmdyb3VwKSwgYWxwaGEgPSAwLjUpICsKICBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYyg3MDAsMzAwKSkgKwogIHRoZW1lX2J3KCkKYGBgCgojIEdyb3VwIEF2ZXJhZ2VzIFdpdGggTW9yZSBTbW9vdGhpbmcKCk1heWJlIHdlIHNob3VsZCBzbW9vdGggZXZlbiBtb3JlLiBTYW1wbGUgc2l6ZSA9IDEwISAKCmBgYHtyfQpkYXRhIDwtIGRhdGEgJT4lCiAgZ3JvdXBfYnkobWFpbmdyb3VwLCByZWNvcmRpbmdfbmFtZSkgJT4lCiAgbXV0YXRlKHlfbWEyID0gUmNwcFJvbGw6OnJvbGxfbWVhbih5LCBuID0gMTAsIGZpbGwgPSAwKSkKCiMgZGF0YSAlPiUKIyAgIGZpbHRlcihyZWNvcmRpbmdfbmFtZSA9PSAiQWRhbV9Hb29kIikgJT4lCiMgICBnZ3Bsb3QoKSArCiMgICBnZW9tX2xpbmUoYWVzKHggPSBnYXplX3BvaW50X2luZGV4LCB5ID0geSksIGNvbG9yID0gImJsdWUiLCBhbHBoYSA9IDAuMjUsIHNpemUgPSAwLjUpICsKIyAgIGdlb21fbGluZShhZXMoeCA9IGdhemVfcG9pbnRfaW5kZXgsIHkgPSB5X21hMiksIGNvbG9yID0gInJlZCIsIHNpemUgPSAwLjIpICsKIyAgIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDQ3NSwgMzI1KSkgKwojICAgdGhlbWVfYncoKQoKYXZlcmFnZWRfeSA8LSBkYXRhICU+JQogIGdyb3VwX2J5KG1haW5ncm91cCwgZ2F6ZV9wb2ludF9pbmRleCkgJT4lCiAgc3VtbWFyaXNlKHlfbWVhbiA9IG1lYW4oeV9tYTIsIG5hLnJtID0gVCksCiAgICAgICAgICAgIHlfc2QgPSBzZCh5X21hMiwgbmEucm0gPSBUKSwKICAgICAgICAgICAgeV9jb3VudCA9IG4oKSwKICAgICAgICAgICAgeV9zZSA9IHlfc2Qvc3FydCh5X2NvdW50KSkKCmxpYnJhcnkoaHJicnRoZW1lcykKYXZlcmFnZWRfeSAlPiUKICBnZ3Bsb3QoKSArIAogIGdlb21fbGluZShhZXMoeCA9IGdhemVfcG9pbnRfaW5kZXgsIHkgPSB5X21lYW4sIGNvbG9yID0gbWFpbmdyb3VwKSwgc2l6ZSA9IDAuOCkgKwogIGdlb21fcmliYm9uKGFlcyh4ID0gZ2F6ZV9wb2ludF9pbmRleCwgCiAgICAgICAgICAgICAgICAgIHltaW4gPSB5X21lYW4teV9zZSwgCiAgICAgICAgICAgICAgICAgIHltYXggPSB5X21lYW4reV9zZSwKICAgICAgICAgICAgICAgICAgZmlsbCA9IG1haW5ncm91cCksIGFscGhhID0gMC41KSArCiAgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTIwMCwwKSkgKwogIGZhY2V0X3dyYXAoIm1haW5ncm91cCIpICsKICBsYWJzKHggPSAidGltZSAobXMpIiwgeSA9ICJwaXhlbHMiLCB0aXRsZSA9ICJGaWd1cmUgMS4gVmVydGljYWwgRXllIEdhemUgUG9zaXRpb24gQWNyb3NzIE9uZSBBU0wgTmFycmF0aXZlIikgKwogIGd1aWRlcyhjb2xvciA9IEYsIGZpbGwgPSBGKSArCiAgdGhlbWVfaXBzdW1fcmMoKQoKYXZlcmFnZWRfeSAlPiUKICBnZ3Bsb3QoKSArIAogIGdlb21fbGluZShhZXMoeCA9IGdhemVfcG9pbnRfaW5kZXgsIHkgPSB5X21lYW4sIGNvbG9yID0gbWFpbmdyb3VwKSkgKwogIGdlb21fcmliYm9uKGFlcyh4ID0gZ2F6ZV9wb2ludF9pbmRleCwgCiAgICAgICAgICAgICAgICAgIHltaW4gPSB5X21lYW4teV9zZSwgCiAgICAgICAgICAgICAgICAgIHltYXggPSB5X21lYW4reV9zZSwKICAgICAgICAgICAgICAgICAgZmlsbCA9IG1haW5ncm91cCksIGFscGhhID0gMC41KSArCiAgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTIwMCwwKSkgKwogIHRoZW1lX2J3KCkKCmF2ZXJhZ2VkX3kgJT4lCiAgZmlsdGVyKG1haW5ncm91cCA9PSAiRGVhZkVhcmx5IiB8IG1haW5ncm91cCA9PSAiSGVhcmluZ05vdmljZSIpICU+JQogIGdncGxvdCgpICsgCiAgZ2VvbV9saW5lKGFlcyh4ID0gZ2F6ZV9wb2ludF9pbmRleCwgeSA9IHlfbWVhbiwgY29sb3IgPSBtYWluZ3JvdXApLCBzaXplID0gMC44KSArCiAgZ2VvbV9yaWJib24oYWVzKHggPSBnYXplX3BvaW50X2luZGV4LCAKICAgICAgICAgICAgICAgICAgeW1pbiA9IHlfbWVhbi15X3NlLCAKICAgICAgICAgICAgICAgICAgeW1heCA9IHlfbWVhbit5X3NlLAogICAgICAgICAgICAgICAgICBmaWxsID0gbWFpbmdyb3VwKSwgYWxwaGEgPSAwLjEpICsKICBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYyg3MDAsMzAwKSkgKwogIGxhYnMoeCA9ICJ0aW1lIChtcykiLCB5ID0gInBpeGVscyIsIHRpdGxlID0gIkZpZ3VyZSAyLiBEZWFmIEVhcmx5IFNpZ25lcnMgdnMuIEhlYXJpbmcgTm92aWNlIFNpZ25lcnMiLCBjb2xvciA9ICIiLCBmaWxsID0gIiIpICsKICB0aGVtZV9pcHN1bV9yYygpCgpgYGAKCiMgRXZlcnl0aGluZyBFbHNlIFRoYXQgV2FzIEFscmVhZHkgSGVyZQoKTmV4dCBsZXQncyBwbG90IHRoZSBtb21lbnRzIHdoZXJlIHNwYXRpYWwgcmVmZXJlbmNpbmcgaGFwcGVucy4gVGhvc2UgYXJlIGZyYW1lcwoKMS4gMTk4IHRvIDIyMwoxLiAyNjUgdG8gMjg4CjEuIDM1MiB0byAzODAKClRoZSBtYXggZ2F6ZXBvaW50aW5kZXggaXMgYXJvdW5kIDI1ODAuIEF0IDEyMCBIeiwgdGhhdCdzIDIxLjUgc2Vjb25kcyB3aGljaCBpcyBqdXN0IHJpZ2h0LCB0aGF0J3MgdGhlIGxlbmd0aC4gTGV0J3MgZ28gYWhlYWQgYW5kIGNvbnZlcnQgZ2F6ZXBvaW50aW5kZXggdG8gc2Vjb25kcy4gIAoKU28gd2UganVzdCBoYXZlIHRvIGNvbnZlcnQgZnJhbWVzIHRvIGdhemVwb2ludGluZGV4LiBUaGUgdmlkZW8gaXMgYSB0b3RhbCBvZiA1MzYgZnJhbWVzLCBhdCAyNSBGUFMgdGhhdCdzIDIxLjUgc2Vjb25kcy4gNTM1LzI1ID0gMjEuNSwgc28gd2UgZGl2aWRlIGFsbCB0aG9zZSBmcmFtZXMgYnkgMjUuIAoKMS4gNy45MnMgdG8gOC45MnMKMS4gMTAuNnMgdG8gMTEuNTJzCjEuIDE0LjA4cyB0byAxNS4ycyAKCkFuZCBwbG90IHRob3NlIQoKYGBge3J9CmRhdGEgPC0gZGF0YSAlPiUKICByb3d3aXNlKCkgJT4lCiAgbXV0YXRlKHNlY3MgPSBnYXplX3BvaW50X2luZGV4LzEyMCkKCmRhdGEgJT4lCiAgZ2dwbG90KGFlcyh4ID0gc2VjcywgeSA9IHksIGNvbG9yID0gbWFpbmdyb3VwLCBncm91cCA9IG5hbWUpKSArIAogIHNjYWxlX3lfcmV2ZXJzZSgpICsgCiAgZ2VvbV9saW5lKCkgKyAKICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSA3LjkyLCB4bWF4ID0gOC45MiwgeW1pbiA9IDAsIHltYXggPSA5MDAsCiAgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gMTAuNiwgeG1heCA9IDExLjUyLCB5bWluID0gMCwgeW1heCA9IDkwMCwKICBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSAxNC4wOCwgeG1heCA9IDE1LjIsIHltaW4gPSAwLCB5bWF4ID0gOTAwLAogIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogIHRoZW1lX2J3KCkKYGBgCgpNYXliZSBlYXNpZXIgaWYgd2Ugc2VwYXJhdGUgZ3JvdXBzIG9mIHNpZ25lcnMuIAoKYGBge3J9CmRhdGEgJT4lCiAgZ2dwbG90KGFlcyh4ID0gc2VjcywgeSA9IHksIGNvbG9yID0gbWFpbmdyb3VwLCBncm91cCA9IG5hbWUpKSArIAogIHNjYWxlX3lfcmV2ZXJzZSgpICsgCiAgZ2VvbV9saW5lKGFscGhhID0gMC41KSArIAogIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IDcuOTIsIHhtYXggPSA4LjkyLCB5bWluID0gMCwgeW1heCA9IDkwMCwKICBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSAxMC42LCB4bWF4ID0gMTEuNTIsIHltaW4gPSAwLCB5bWF4ID0gOTAwLAogIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IDE0LjA4LCB4bWF4ID0gMTUuMiwgeW1pbiA9IDAsIHltYXggPSA5MDAsCiAgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgZmFjZXRfZ3JpZChtYWluZ3JvdXAgfiAuKSArCiAgdGhlbWVfYncoKSArCiAgZ3VpZGVzKGNvbG9yID0gRkFMU0UpCmBgYAoKTmV4dCwgd2UncmUgZ29pbmcgdG8gYWRkIEFPSSBwb3NpdGlvbiBpbmZvcm1hdGlvbi4gV2UncmUgZ29pbmcgdG8gcHVsbCBpbiBpbmZvcm1hdGlvbiBvbiBzaWduZXJzJyByaWdodCBoYW5kIHBvc2l0aW9uIChhbmQgdGhlbiBhcHBseSB0aGUgc2FtZSBpZGVhIHRvIG90aGVyIGJvZHkgcGFydHMpLiBJIHN1Y2Nlc3NmdWxseSB3cm90ZSBhIGZ1bmN0aW9uIGNhbGxlZCBgZ2V0X3h5X3RpbWVzdGFtcGAgdG8gZG8gdGhpcyEgWWF5LiBJJ20gY2h1ZmZlZCwgYXMgdGhlIEJyaXRpc2ggd291bGQgc2F5LgoKTGV0J3MgdHJ5IHRoaXMgb24gU3RlcGhhbmllJ3MgZGF0YS4gTGV0J3Mgc2VlIGlmIHdlIGNhbiBmaW5kIGEgY29ycmVsYXRpb24gYmV0d2VlbiBhbnkgb2YgdGhvc2UgYW5kIHRoZSBleWUgZ2F6ZSB5LXBvc2l0aW9uLiAKCmBgYHtyfQoKIyBXZSBhZGQgb25lIG1vcmUgcm93IHRvIHRoZSB4eV90aW1lc3RhbXAgZGF0YSB0byBhbGlnbiBpdCB3aXRoIHRoZSBlbmQgb2YgdGhlIGV5ZSBnYXplIGRhdGEuCnJoYW5kIDwtIGdldF94eV90aW1lc3RhbXAoImFvaV9wb3NpdGlvbi9DaW5keV9iZWFyc19GV19Qb3NpdGlvbiBvZiBSaWdodCBIYW5kLnR4dCIpICU+JQogIGFkZF9yb3coc2VjID0gMjEuNSwgeCA9IDY0MC4xNiwgeSA9IDEwNTUuOTcpCmxoYW5kIDwtIGdldF94eV90aW1lc3RhbXAoImFvaV9wb3NpdGlvbi9DaW5keV9iZWFyc19GV19Qb3NpdGlvbiBvZiBMZWZ0IEhhbmQudHh0IikgJT4lCiAgYWRkX3JvdyhzZWMgPSAyMS41LCB4ID0gNzAzLjc0LCB5ID0gMTA1OC4zOSkKbW91dGggPC0gZ2V0X3h5X3RpbWVzdGFtcCgiYW9pX3Bvc2l0aW9uL0NpbmR5X2JlYXJzX0ZXX1Bvc2l0aW9uIG9mIG1vdXRoIHNtYWxsLnR4dCIpICU+JQogIGFkZF9yb3coc2VjID0gMjEuNSwgeCA9IDY1Ni4zNywgeSA9IDM3My45OSkKCiMgR2V0IFN0ZXBoYW5pZSdzIGRhdGEKc3RlcGggPC0gZmlsdGVyKGRhdGEsIG5hbWUgPT0gIlN0ZXBoYW5pZSIpCgpzdGVwaCAlPiUKICBnZ3Bsb3QoYWVzKHggPSBzZWNzLCB5ID0geSkpICsgCiAgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTIwMCwwKSwgZXhwYW5kID0gYygwLDApKSArIAogIGdlb21fbGluZShhbHBoYSA9IDEsIGNvbG9yID0gInB1cnBsZSIpICsgCiAgIyBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSA3LjkyLCB4bWF4ID0gOC45MiwgeW1pbiA9IDAsIHltYXggPSAxMjAwLAogICMgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgIyBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSAxMC42LCB4bWF4ID0gMTEuNTIsIHltaW4gPSAwLCB5bWF4ID0gMTIwMCwKICAjIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogICMgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gMTQuMDgsIHhtYXggPSAxNS4yLCB5bWluID0gMCwgeW1heCA9IDEyMDAsCiAgIyBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICAjIGdlb21fc3RlcChkYXRhID0gcmhhbmQsIGFlcyh4ID0gc2VjLCB5ID0geSksIGNvbG9yID0gInJlZCIsIGxpbmV0eXBlID0gImxvbmdkYXNoIiwgYWxwaGEgPSAwLjUpICsgCiAgIyBnZW9tX3N0ZXAoZGF0YSA9IGxoYW5kLCBhZXMoeCA9IHNlYywgeSA9IHkpLCBjb2xvciA9ICJibHVlIiwgbGluZXR5cGUgPSAibG9uZ2Rhc2giLCBhbHBoYSA9IDAuNSkgKyAKICAjIGdlb21fc3RlcChkYXRhID0gbW91dGgsIGFlcyh4ID0gc2VjLCB5ID0geSksIGNvbG9yID0gImJsYWNrIiwgbGluZXR5cGUgPSAibG9uZ2Rhc2giLCBhbHBoYSA9IDAuNSkgKyAKICAjIGFubm90YXRlKCJ0ZXh0IiwgbGFiZWwgPSAiUmlnaHQgSGFuZCIsIHggPSAzLCB5ID0gMTAwMCwgY29sb3IgPSAicmVkIiwgYWxwaGEgPSAwLjUpICsKICAjIGFubm90YXRlKCJ0ZXh0IiwgbGFiZWwgPSAiTGVmdCBIYW5kIiwgeCA9IDMsIHkgPSAxMTAwLCBjb2xvciA9ICJibHVlIiwgYWxwaGEgPSAwLjUpICsKICAjIGFubm90YXRlKCJ0ZXh0IiwgbGFiZWwgPSAiTW91dGgiLCB4ID0gMywgeSA9IDIwMCwgY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IDAuNSkgKwogIGdndGl0bGUoIlN0ZXBoYW5pZSIpICsKICB0aGVtZV9idygpICsKICB0aGVtZShwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCkpCgpzdGVwaCAlPiUKICBnZ3Bsb3QoYWVzKHggPSBzZWNzLCB5ID0geSkpICsgCiAgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTIwMCwwKSwgZXhwYW5kID0gYygwLDApKSArIAogIGdlb21fbGluZShhbHBoYSA9IDEsIGNvbG9yID0gInB1cnBsZSIpICsgCiAgIyBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSA3LjkyLCB4bWF4ID0gOC45MiwgeW1pbiA9IDAsIHltYXggPSAxMjAwLAogICMgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgIyBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSAxMC42LCB4bWF4ID0gMTEuNTIsIHltaW4gPSAwLCB5bWF4ID0gMTIwMCwKICAjIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogICMgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gMTQuMDgsIHhtYXggPSAxNS4yLCB5bWluID0gMCwgeW1heCA9IDEyMDAsCiAgIyBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKIyAgZ2VvbV9zdGVwKGRhdGEgPSByaGFuZCwgYWVzKHggPSBzZWMsIHkgPSB5KSwgY29sb3IgPSAicmVkIiwgbGluZXR5cGUgPSAibG9uZ2Rhc2giLCBhbHBoYSA9IDAuNSkgKyAKIyAgZ2VvbV9zdGVwKGRhdGEgPSBsaGFuZCwgYWVzKHggPSBzZWMsIHkgPSB5KSwgY29sb3IgPSAiYmx1ZSIsIGxpbmV0eXBlID0gImxvbmdkYXNoIiwgYWxwaGEgPSAwLjUpICsgCiAgZ2VvbV9zdGVwKGRhdGEgPSBtb3V0aCwgYWVzKHggPSBzZWMsIHkgPSB5KSwgY29sb3IgPSAiYmxhY2siLCBsaW5ldHlwZSA9ICJsb25nZGFzaCIsIGFscGhhID0gMC41KSArIAojIGFubm90YXRlKCJ0ZXh0IiwgbGFiZWwgPSAiUmlnaHQgSGFuZCIsIHggPSAzLCB5ID0gMTAwMCwgY29sb3IgPSAicmVkIiwgYWxwaGEgPSAwLjUpICsKIyAgYW5ub3RhdGUoInRleHQiLCBsYWJlbCA9ICJMZWZ0IEhhbmQiLCB4ID0gMywgeSA9IDExMDAsIGNvbG9yID0gImJsdWUiLCBhbHBoYSA9IDAuNSkgKwogIGFubm90YXRlKCJ0ZXh0IiwgbGFiZWwgPSAiTW91dGgiLCB4ID0gMywgeSA9IDI1MCwgY29sb3IgPSAiYmxhY2siLCBhbHBoYSA9IDAuNSkgKwogIGdndGl0bGUoIlN0ZXBoYW5pZSIpICsKICB0aGVtZV9idygpICsKICB0aGVtZShwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCkpCgpzdGVwaCAlPiUKICBnZ3Bsb3QoYWVzKHggPSBzZWNzLCB5ID0geSkpICsgCiAgc2NhbGVfeV9yZXZlcnNlKGxpbWl0cyA9IGMoMTIwMCwwKSwgZXhwYW5kID0gYygwLDApKSArIAogIGdlb21fbGluZShhbHBoYSA9IDEsIGNvbG9yID0gInB1cnBsZSIpICsgCiAgIyBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSA3LjkyLCB4bWF4ID0gOC45MiwgeW1pbiA9IDAsIHltYXggPSAxMjAwLAogICMgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgIyBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSAxMC42LCB4bWF4ID0gMTEuNTIsIHltaW4gPSAwLCB5bWF4ID0gMTIwMCwKICAjIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogICMgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gMTQuMDgsIHhtYXggPSAxNS4yLCB5bWluID0gMCwgeW1heCA9IDEyMDAsCiAgIyBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICBnZW9tX3N0ZXAoZGF0YSA9IHJoYW5kLCBhZXMoeCA9IHNlYywgeSA9IHkpLCBjb2xvciA9ICJyZWQiLCBsaW5ldHlwZSA9ICJsb25nZGFzaCIsIGFscGhhID0gMC41KSArIAojICBnZW9tX3N0ZXAoZGF0YSA9IGxoYW5kLCBhZXMoeCA9IHNlYywgeSA9IHkpLCBjb2xvciA9ICJibHVlIiwgbGluZXR5cGUgPSAibG9uZ2Rhc2giLCBhbHBoYSA9IDAuNSkgKyAKICBnZW9tX3N0ZXAoZGF0YSA9IG1vdXRoLCBhZXMoeCA9IHNlYywgeSA9IHkpLCBjb2xvciA9ICJibGFjayIsIGxpbmV0eXBlID0gImxvbmdkYXNoIiwgYWxwaGEgPSAwLjUpICsgCiAgYW5ub3RhdGUoInRleHQiLCBsYWJlbCA9ICJSaWdodCBIYW5kIiwgeCA9IDMsIHkgPSAxMDAwLCBjb2xvciA9ICJyZWQiLCBhbHBoYSA9IDAuNSkgKwojICBhbm5vdGF0ZSgidGV4dCIsIGxhYmVsID0gIkxlZnQgSGFuZCIsIHggPSAzLCB5ID0gMTEwMCwgY29sb3IgPSAiYmx1ZSIsIGFscGhhID0gMC41KSArCiAgYW5ub3RhdGUoInRleHQiLCBsYWJlbCA9ICJNb3V0aCIsIHggPSAzLCB5ID0gMjUwLCBjb2xvciA9ICJibGFjayIsIGFscGhhID0gMC41KSArCiAgZ2d0aXRsZSgiU3RlcGhhbmllIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKHBhbmVsLmdyaWQubWlub3IueSA9IGVsZW1lbnRfYmxhbmsoKSkKCnN0ZXBoICU+JQogIGdncGxvdChhZXMoeCA9IHNlY3MsIHkgPSB5KSkgKyAKICBzY2FsZV95X3JldmVyc2UobGltaXRzID0gYygxMjAwLDApLCBleHBhbmQgPSBjKDAsMCkpICsgCiAgZ2VvbV9saW5lKGFscGhhID0gMSwgY29sb3IgPSAicHVycGxlIikgKyAKICAjIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IDcuOTIsIHhtYXggPSA4LjkyLCB5bWluID0gMCwgeW1heCA9IDEyMDAsCiAgIyBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICAjIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IDEwLjYsIHhtYXggPSAxMS41MiwgeW1pbiA9IDAsIHltYXggPSAxMjAwLAogICMgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgIyBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSAxNC4wOCwgeG1heCA9IDE1LjIsIHltaW4gPSAwLCB5bWF4ID0gMTIwMCwKICAjIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogIGdlb21fc3RlcChkYXRhID0gcmhhbmQsIGFlcyh4ID0gc2VjLCB5ID0geSksIGNvbG9yID0gInJlZCIsIGxpbmV0eXBlID0gImxvbmdkYXNoIiwgYWxwaGEgPSAwLjUpICsgCiAgZ2VvbV9zdGVwKGRhdGEgPSBsaGFuZCwgYWVzKHggPSBzZWMsIHkgPSB5KSwgY29sb3IgPSAiYmx1ZSIsIGxpbmV0eXBlID0gImxvbmdkYXNoIiwgYWxwaGEgPSAwLjUpICsgCiAgZ2VvbV9zdGVwKGRhdGEgPSBtb3V0aCwgYWVzKHggPSBzZWMsIHkgPSB5KSwgY29sb3IgPSAiYmxhY2siLCBsaW5ldHlwZSA9ICJsb25nZGFzaCIsIGFscGhhID0gMC41KSArIAogIGFubm90YXRlKCJ0ZXh0IiwgbGFiZWwgPSAiUmlnaHQgSGFuZCIsIHggPSAzLCB5ID0gMTAwMCwgY29sb3IgPSAicmVkIiwgYWxwaGEgPSAwLjUpICsKICBhbm5vdGF0ZSgidGV4dCIsIGxhYmVsID0gIkxlZnQgSGFuZCIsIHggPSAzLCB5ID0gMTEwMCwgY29sb3IgPSAiYmx1ZSIsIGFscGhhID0gMC41KSArCiAgYW5ub3RhdGUoInRleHQiLCBsYWJlbCA9ICJNb3V0aCIsIHggPSAzLCB5ID0gMjUwLCBjb2xvciA9ICJibGFjayIsIGFscGhhID0gMC41KSArCiAgZ2d0aXRsZSgiU3RlcGhhbmllIikgKwogIHRoZW1lX2J3KCkgKwogIHRoZW1lKHBhbmVsLmdyaWQubWlub3IueSA9IGVsZW1lbnRfYmxhbmsoKSkKYGBgCgpOb3cgbGV0J3Mgd29yayBvbiBjb3JyZWxhdGlvbnMuIEZpcnN0LCBvdXIgQU9JIHZlY3RvcnMgYXJlIG5vdCB0aGUgc2FtZSBzaXplIGFzIG91ciBleWUgZ2F6ZSB2ZWN0b3JzLCBhbmQgdGhlIHgveSBwb3NpdGlvbiBpcyBpcnJlZ3VsYXJseSBzcGFjZWQgYWNyb3NzIHRpbWUgKGlycmVndWxhcmx5IHNwYWNlZCBrZXkgZnJhbWVzKS4gCmBgYHtyfQojIFRoZSBmb2xsb3dpbmcgY29kZSB3aWxsICJleHBhbmQiIHRoZSByaGFuZCBkYXRhIHZlY3RvcnMgdG8gZml0IHRoZSBsZW5ndGggb2YgU3RlcGhhbmllJ3MgZGF0YSB2ZWN0b3JzLgp0aW1lX2luZGV4IDwtIHN0ZXBoJHNlY3MKY2xvc2VzdCA8LSBmdW5jdGlvbih4KXsKICB3aGljaC5taW4oYWJzKHRpbWVfaW5kZXgteCkpCn0KCmluZGV4X2xvYyA8LSBtYXBfaW50KHJoYW5kJHNlYywgY2xvc2VzdCkKCnJoYW5kIDwtIGNiaW5kKHJoYW5kLCB0aW1lX2luZGV4W2luZGV4X2xvY10pICU+JQogIHNlbGVjdCgtc2VjKSAlPiUKICByZW5hbWUoc2VjID0gInRpbWVfaW5kZXhbaW5kZXhfbG9jXSIpICU+JQogIHNlbGVjdChzZWMsIHgsIHkpCgpyaGFuZF9mdWxsIDwtIHNlbGVjdChzdGVwaCwgc2VjcykgJT4lCiAgcmVuYW1lKHNlYyA9IHNlY3MpICU+JQogIGxlZnRfam9pbihyaGFuZCkgJT4lCiAgZmlsbCh4KSAlPiUKICBmaWxsKHkpICU+JQogIHNsaWNlKDE6KG5yb3coLiktMSkpCgpyaGFuZF9mdWxsIDwtIHJoYW5kX2Z1bGwgJT4lCiAgZmlsdGVyKHNlYyA8IHJoYW5kJHNlY1sxNzJdKSAlPiUKICBmaWx0ZXIoc2VjID49IHJoYW5kJHNlY1syXSkKCnN0ZXBoIDwtIHN0ZXBoICU+JQogIGZpbHRlcihzZWNzIDwgcmhhbmQkc2VjWzE3Ml0pICU+JQogIGZpbHRlcihzZWNzID49IHJoYW5kJHNlY1syXSkKCmEgPC0gcmhhbmRfZnVsbCR5CmEgPC0gYVsxOmxlbmd0aChhKS0xXSAjIFNob3J0ZW4gaXQgYnkgb25lIGVsZW1lbnQKYiA8LSBzdGVwaCR5CgojIFRoZW4gcnVuIGNvcnJlbGF0aW9ucwpjb3IoYSxiLCB1c2UgPSAiY29tcGxldGUub2JzIikgIyBiYXNpYyBjb3JyZWxhdGlvbgp0aGF0IDwtIGNjZihhLGIsIGxhZy5tYXggPSA0MDAsIHR5cGUgPSAiY29ycmVsYXRpb24iLCBuYS5hY3Rpb24gPSBuYS5wYXNzLCBwbG90ID0gVCkgIyBhdXRvLWNvcnJlbGF0aW9uCmBgYAoKCkxldCdzIHNlcGFyYXRlIG91dCBpbmRpdmlkdWFsIHNpZ25lcnMuIAoKYGBge3J9Cm1ha2Vfc2lnbmVyX3Bsb3RzIDwtIGZ1bmN0aW9uKGdyb3VwbmFtZSwgbGluZV9jb2xvcikgewogIGRhdGEgJT4lCiAgZmlsdGVyKG1haW5ncm91cCA9PSBncm91cG5hbWUpICU+JQogIGdncGxvdChhZXMoeCA9IHNlY3MsIHkgPSB5KSkgKyAKICBzY2FsZV95X3JldmVyc2UoKSArIAogIGdlb21fbGluZShhbHBoYSA9IDEsIGNvbG9yID0gbGluZV9jb2xvcikgKyAKICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSA3LjkyLCB4bWF4ID0gOC45MiwgeW1pbiA9IDAsIHltYXggPSA5MDAsCiAgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gMTAuNiwgeG1heCA9IDExLjUyLCB5bWluID0gMCwgeW1heCA9IDkwMCwKICBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSAxNC4wOCwgeG1heCA9IDE1LjIsIHltaW4gPSAwLCB5bWF4ID0gOTAwLAogIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogIGdlb21fc3RlcChkYXRhID0gcmhhbmQsIGFlcyh4ID0gc2VjLCB5ID0geSksIGNvbG9yID0gInJlZCIsIGxpbmV0eXBlID0gImxvbmdkYXNoIiwgYWxwaGEgPSAwLjUpICsgCiAgZ2VvbV9zdGVwKGRhdGEgPSBsaGFuZCwgYWVzKHggPSBzZWMsIHkgPSB5KSwgY29sb3IgPSAiYmx1ZSIsIGxpbmV0eXBlID0gImxvbmdkYXNoIiwgYWxwaGEgPSAwLjUpICsgCiAgZ2VvbV9zdGVwKGRhdGEgPSBtb3V0aCwgYWVzKHggPSBzZWMsIHkgPSB5KSwgY29sb3IgPSAiYmxhY2siLCBsaW5ldHlwZSA9ICJsb25nZGFzaCIsIGFscGhhID0gMC41KSArIAogIGFubm90YXRlKCJ0ZXh0IiwgbGFiZWwgPSAiUmlnaHQgSGFuZCIsIHggPSAzLCB5ID0gMTAwMCwgY29sb3IgPSAicmVkIiwgYWxwaGEgPSAwLjUpICsKICBhbm5vdGF0ZSgidGV4dCIsIGxhYmVsID0gIkxlZnQgSGFuZCIsIHggPSAzLCB5ID0gMTEwMCwgY29sb3IgPSAiYmx1ZSIsIGFscGhhID0gMC41KSArCiAgYW5ub3RhdGUoInRleHQiLCBsYWJlbCA9ICJNb3V0aCIsIHggPSAzLCB5ID0gMjAwLCBjb2xvciA9ICJibGFjayIsIGFscGhhID0gMC41KSArCiAgZmFjZXRfZ3JpZChuYW1lIH4gLikgKwogIGdndGl0bGUoZ3JvdXBuYW1lKSArCiAgdGhlbWVfYncoKQp9CgptYWtlX3NpZ25lcl9wbG90cygiRGVhZkVhcmx5IiwgInJlZCIpCm1ha2Vfc2lnbmVyX3Bsb3RzKCJEZWFmTGF0ZSIsICJkYXJrIGdyZWVuIikKbWFrZV9zaWduZXJfcGxvdHMoIkhlYXJpbmdMYXRlIiwgImJsdWUiKQptYWtlX3NpZ25lcl9wbG90cygiSGVhcmluZ05vdmljZSIsICJwdXJwbGUiKQpgYGAKCk9rYXkgc28gd2l0aCBFYXJseSBBU0wgb2J2aW91c2x5IHZlcnkgc3RlYWR5IGdhemUuIE5vdmljZUFTTCBoYXMgbG90IG9mIGRvd25zaGlmdHMuIFNvbWUgYWxpZ24gd2l0aCBzcGF0aWFsIHJlZmVyZW5jaW5nLCBzb21lIGRvIG5vdC4gV2UgbmVlZCBtb3JlIG9mIHRoZW0gKGxldCdzIGxvb2sgYXQgb3RoZXIgc3RvcmllcyB3IGJldHRlciBkYXRhKS4gCgoKIyBNaWRhcyBGb3J3YXJkCgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIEdldCBNaWRhcyBkYXRhCmRhdGEgPC0gcmVhZF9jc3YoIi4uL0FkdWx0IERhdGEvcmF3ZGF0YS9taWRhc2Z3LmNzdiIpICU+JQogIGNsZWFuX25hbWVzKCkgJT4lCiAgcmVuYW1lKHkgPSBnYXplX3BvaW50X3lfbWNfc3B4LAogICAgICAgICBsYW5ndWFnZSA9IGxhbmd1YWdlX3ZhbHVlLAogICAgICAgICBuYW1lID0gcGFydGljaXBhbnRfbmFtZSwKICAgICAgICAgZ3JvdXAgPSBncm91cF92YWx1ZSkKCiMgUHVsbCBjbGVhbiBuYW1lcyBhbmQgam9pbiB0byBkYXRhCmNsZWFubmFtZXMgPC0gcmVhZF9jc3YoInBhcnRuYW1lcy5jc3YiKSAlPiUKICBkaXN0aW5jdCgpICU+JQogIHJlbmFtZShuYW1lID0gcGFydGljaXBhbnQpCgpkYXRhIDwtIGRhdGEgJT4lIGxlZnRfam9pbihjbGVhbm5hbWVzLCBieSA9ICJuYW1lIikgJT4lCiAgc2VsZWN0KC1uYW1lKSAlPiUKICByZW5hbWUobmFtZSA9IG5ld19wYXJ0aWNpcGFudCkgJT4lCiAgZmlsdGVyKCFpcy5uYShuYW1lKSkKCiMgUHVsbCBmaW5hbCBncm91cCBhc3NpZ25tZW50cyBhbmQgam9pbiB0byBkYXRhCmNsZWFuZ3JvdXBzIDwtIHJlYWRfY3N2KCJmaW5hbGRhdGFzZXQuY3N2IikgJT4lCiAgc2VsZWN0KHBhcnRpY2lwYW50LCBtYWluZ3JvdXApICU+JQogIHJlbmFtZShuYW1lID0gcGFydGljaXBhbnQpICU+JQogIGRpc3RpbmN0KCkKCmRhdGEgPC0gZGF0YSAlPiUgbGVmdF9qb2luKGNsZWFuZ3JvdXBzLCBieSA9ICJuYW1lIikgJT4lCiAgc2VsZWN0KC1ncm91cCkKCiMgTGV0J3MgZmluZCBvdXQgd2hvIHdhcyBOT1QgaW5jbHVkZWQgaW4gVGhyZWUgQmVhcnMKZXhjbHVkZWQgPC0gcmVhZF9jc3YoImZpbmFsZGF0YXNldC5jc3YiKSAlPiUKICBzZWxlY3QocGFydGljaXBhbnQsIG1haW5ncm91cCwgc3RvcnksIGRpcmVjdGlvbiwgZXllX2V4Y2x1ZGUpICU+JQogIGZpbHRlcihzdG9yeSA9PSAiS2luZ01pZGFzIiAmIGRpcmVjdGlvbiA9PSAiZm9yd2FyZCIpICU+JQogIHJlbmFtZShuYW1lID0gcGFydGljaXBhbnQpICU+JQogIHNlbGVjdChuYW1lLCBleWVfZXhjbHVkZSkKCmRhdGEgPC0gZGF0YSAlPiUgbGVmdF9qb2luKGV4Y2x1ZGVkLCBieSA9ICJuYW1lIikgJT4lCiAgZmlsdGVyKCFleWVfZXhjbHVkZSkgJT4lCiAgZmlsdGVyKCFpcy5uYShleWVfZXhjbHVkZSkpCgpkYXRhICU+JSBzZWxlY3QobmFtZSwgbWFpbmdyb3VwKSAlPiUgZGlzdGluY3QoKQpgYGAKCk5vdyBsZXQncyBncmFwaCEhIAoKSG0uIE9uZSBwZXJzb24gc2VlbXMgd3JvbmcuIApgYGB7cn0KZGF0YSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBnYXplX3BvaW50X2luZGV4LCB5ID0geSwgY29sb3IgPSBtYWluZ3JvdXAsIGdyb3VwID0gbmFtZSkpICsgZ2VvbV9saW5lKCkgKyBzY2FsZV95X3JldmVyc2UoKQpgYGAKT2theSBpdCdzIEplc3NlJ3MgZGF0YSB0aGF0IHNlZW1zIG9mZi4gV2UnbGwgcmVtb3ZlIGhpbSBmb3Igbm93IGFuZCBjb21lIGJhY2sgdG8gaXQsIGZpZ3VyZSBvdXQgd2h5LiAKYGBge3J9CmRhdGEgJT4lIGZpbHRlcihnYXplX3BvaW50X2luZGV4ID4gMzAwMDApICU+JSBzZWxlY3QobmFtZSkgJT4lIGRpc3RpbmN0KCkgJT4lIGhlYWQoKQpgYGAKCmBgYHtyfQpkYXRhIDwtIGRhdGEgJT4lCiAgZmlsdGVyKG5hbWUgIT0gIkplc3NlIikKCmRhdGEgJT4lCiAgZ2dwbG90KGFlcyh4ID0gZ2F6ZV9wb2ludF9pbmRleCwgeSA9IHksIGNvbG9yID0gbWFpbmdyb3VwLCBncm91cCA9IG5hbWUpKSArIGdlb21fbGluZSgpICsgCiAgc2NhbGVfeV9yZXZlcnNlKCkgKwogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDAsNDUwMCkpCmBgYAoKTmV4dCBsZXQncyBwbG90IHRoZSBtb21lbnRzIHdoZXJlIHNwYXRpYWwgcmVmZXJlbmNpbmcgaGFwcGVucy4gVGhvc2UgYXJlIGZyYW1lcwoKMS4gMjQ4IHRvIDQyNwoxLiA0NjAgdG8gNTA4CjEuIDUxMiB0byA1NjAKCkxpa2UgYmVmb3JlLCB3ZSdsbCBjb252ZXJ0IGdhemVwb2ludGluZGV4IHRvIHNlY29uZHMgKGJ5IGRpdmlkaW5nIDEyMCkgYW5kIGFsbCBmcmFtZXMgdG8gc2Vjb25kcyAoYnkgZGl2aWRpbmcgMjUpLiAKCjEuIDkuOTJzIHRvIDE3LjA4cwoxLiAxOC40cyB0byAyMC4zMnMKMS4gMjAuNDhzIHRvIDIyLjRzIAoKYGBge3J9CmRhdGEgPC0gZGF0YSAlPiUKICByb3d3aXNlKCkgJT4lCiAgbXV0YXRlKHNlY3MgPSBnYXplX3BvaW50X2luZGV4LzEyMCkKCmRhdGEgJT4lCiAgZ2dwbG90KGFlcyh4ID0gc2VjcywgeSA9IHksIGNvbG9yID0gbWFpbmdyb3VwLCBncm91cCA9IG5hbWUpKSArIAogIHNjYWxlX3lfcmV2ZXJzZSgpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgMzcuNSkpICsKICBnZW9tX2xpbmUoKSArIAogIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IDkuOTIsIHhtYXggPSAxNy4wOCwgeW1pbiA9IDAsIHltYXggPSA5MDAsCiAgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gMTguNCwgeG1heCA9IDIwLjMyLCB5bWluID0gMCwgeW1heCA9IDkwMCwKICBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSAyMC40OCwgeG1heCA9IDIyLjQsIHltaW4gPSAwLCB5bWF4ID0gOTAwLAogIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikKYGBgCgpNYXliZSBlYXNpZXIgaWYgd2Ugc2VwYXJhdGUgZ3JvdXBzIG9mIHNpZ25lcnMuIAoKYGBge3J9CmRhdGEgJT4lCiAgZ2dwbG90KGFlcyh4ID0gc2VjcywgeSA9IHksIGNvbG9yID0gbWFpbmdyb3VwLCBncm91cCA9IG5hbWUpKSArIAogIHNjYWxlX3lfcmV2ZXJzZSgpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgMzcuNSkpICsKICBnZW9tX2xpbmUoYWxwaGEgPSAwLjUpICsgCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gOS45MiwgeG1heCA9IDE3LjA4LCB5bWluID0gMCwgeW1heCA9IDkwMCwKICBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSAxOC40LCB4bWF4ID0gMjAuMzIsIHltaW4gPSAwLCB5bWF4ID0gOTAwLAogIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IDIwLjQ4LCB4bWF4ID0gMjIuNCwgeW1pbiA9IDAsIHltYXggPSA5MDAsCiAgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgZmFjZXRfZ3JpZChtYWluZ3JvdXAgfiAuKQpgYGAKCkluZGl2aWR1YWwgc2lnbmVycy4gCgpgYGB7cn0KZGF0YSAlPiUKICBmaWx0ZXIobWFpbmdyb3VwID09ICJEZWFmRWFybHkiKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBzZWNzLCB5ID0geSwgZ3JvdXAgPSBuYW1lKSkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCAzNy41KSkgKwogIHNjYWxlX3lfcmV2ZXJzZSgpICsgCiAgZ2VvbV9saW5lKGFscGhhID0gMSwgY29sb3IgPSAicmVkIikgKyAKICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSA5LjkyLCB4bWF4ID0gMTcuMDgsIHltaW4gPSAwLCB5bWF4ID0gOTAwLAogIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IDE4LjQsIHhtYXggPSAyMC4zMiwgeW1pbiA9IDAsIHltYXggPSA5MDAsCiAgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gMjAuNDgsIHhtYXggPSAyMi40LCB5bWluID0gMCwgeW1heCA9IDkwMCwKICBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICBmYWNldF9ncmlkKG5hbWUgfiAuKSArCiAgZ2d0aXRsZSgiRGVhZkVhcmx5IikKCmRhdGEgJT4lCiAgZmlsdGVyKG1haW5ncm91cCA9PSAiRGVhZkxhdGUiKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBzZWNzLCB5ID0geSwgZ3JvdXAgPSBuYW1lKSkgKyAKICBzY2FsZV95X3JldmVyc2UoKSArIAogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDM3LjUpKSArCiAgZ2VvbV9saW5lKGFscGhhID0gMSwgY29sb3IgPSAiZGFyayBncmVlbiIpICsgCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gOS45MiwgeG1heCA9IDE3LjA4LCB5bWluID0gMCwgeW1heCA9IDkwMCwKICBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSAxOC40LCB4bWF4ID0gMjAuMzIsIHltaW4gPSAwLCB5bWF4ID0gOTAwLAogIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IDIwLjQ4LCB4bWF4ID0gMjIuNCwgeW1pbiA9IDAsIHltYXggPSA5MDAsCiAgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgZmFjZXRfZ3JpZChuYW1lIH4gLikgKwogIGdndGl0bGUoIkRlYWZMYXRlIikKCmRhdGEgJT4lCiAgZmlsdGVyKG1haW5ncm91cCA9PSAiSGVhcmluZ0xhdGUiKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBzZWNzLCB5ID0geSwgZ3JvdXAgPSBuYW1lKSkgKyAKICBzY2FsZV95X3JldmVyc2UoKSArIAogIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDM3LjUpKSArCiAgZ2VvbV9saW5lKGFscGhhID0gMSwgY29sb3IgPSAiYmx1ZSIpICsgCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gOS45MiwgeG1heCA9IDE3LjA4LCB5bWluID0gMCwgeW1heCA9IDkwMCwKICBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSAxOC40LCB4bWF4ID0gMjAuMzIsIHltaW4gPSAwLCB5bWF4ID0gOTAwLAogIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IDIwLjQ4LCB4bWF4ID0gMjIuNCwgeW1pbiA9IDAsIHltYXggPSA5MDAsCiAgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgZmFjZXRfZ3JpZChuYW1lIH4gLikgKwogIGdndGl0bGUoIkhlYXJpbmdMYXRlIikKCmRhdGEgJT4lCiAgZmlsdGVyKG1haW5ncm91cCA9PSAiSGVhcmluZ05vdmljZSIpICU+JQogIGdncGxvdChhZXMoeCA9IHNlY3MsIHkgPSB5LCBncm91cCA9IG5hbWUpKSArIAogIHNjYWxlX3lfcmV2ZXJzZSgpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgMzcuNSkpICsKICBnZW9tX2xpbmUoYWxwaGEgPSAxLCBjb2xvciA9ICJwdXJwbGUiKSArIAogIGFubm90YXRlKCJyZWN0IiwgeG1pbiA9IDkuOTIsIHhtYXggPSAxNy4wOCwgeW1pbiA9IDAsIHltYXggPSA5MDAsCiAgYWxwaGEgPSAuMiwgZmlsbCA9ICJyZWQiKSArCiAgYW5ub3RhdGUoInJlY3QiLCB4bWluID0gMTguNCwgeG1heCA9IDIwLjMyLCB5bWluID0gMCwgeW1heCA9IDkwMCwKICBhbHBoYSA9IC4yLCBmaWxsID0gInJlZCIpICsKICBhbm5vdGF0ZSgicmVjdCIsIHhtaW4gPSAyMC40OCwgeG1heCA9IDIyLjQsIHltaW4gPSAwLCB5bWF4ID0gOTAwLAogIGFscGhhID0gLjIsIGZpbGwgPSAicmVkIikgKwogIGZhY2V0X2dyaWQobmFtZSB+IC4pICsKICBnZ3RpdGxlKCJIZWFyaW5nTm92aWNlIikKYGBg